package com.mindskip.xzs.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mindskip.xzs.context.WebContext;
import com.mindskip.xzs.domain.dto.admin.message.MessagePageDTO;
import com.mindskip.xzs.domain.dto.admin.message.MessageSendDTO;
import com.mindskip.xzs.domain.entity.Message;
import com.mindskip.xzs.domain.entity.MessageUser;
import com.mindskip.xzs.domain.entity.User;
import com.mindskip.xzs.domain.vo.admin.message.MessageVO;
import com.mindskip.xzs.repository.BaseMapper;
import com.mindskip.xzs.repository.MessageMapper;
import com.mindskip.xzs.repository.MessageUserMapper;
import com.mindskip.xzs.service.MessageService;
import com.mindskip.xzs.service.MessageUserService;
import com.mindskip.xzs.service.UserService;
import com.mindskip.xzs.utility.BeanCopyUtils;
import com.mindskip.xzs.utility.DateTimeUtil;
import com.mindskip.xzs.utility.PageInfoUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
public class MessageServiceImpl extends BaseServiceImpl<Message> implements MessageService {

    private final MessageMapper messageMapper;

    private final MessageUserService messageUserService;

    private final WebContext webContext;

    private final UserService userService;

    private final MessageUserMapper messageUserMapper;

    public MessageServiceImpl(BaseMapper<Message> baseMapper, MessageMapper messageMapper, MessageUserService messageUserService, WebContext webContext, UserService userService, MessageUserMapper messageUserMapper) {
        super(baseMapper);
        this.messageMapper = messageMapper;
        this.messageUserService = messageUserService;
        this.webContext = webContext;
        this.userService = userService;
        this.messageUserMapper = messageUserMapper;
    }

    @Override
    public PageInfo<MessageVO> getMessageByPage(MessagePageDTO messagePageDTO) {

        PageHelper.startPage(messagePageDTO.getPageIndex(), messagePageDTO.getPageSize(), "id desc");
        List<Message> messageList = messageMapper.selectByPage(messagePageDTO);
        PageInfo<Message> oldPageInfo = new PageInfo<>(messageList);

        // 根据 messageList 中的每个 message 的 message_id 属性获得 messageUserList
        List<Integer> ids = messageList
                .stream()
                .map(Message::getId)
                .collect(Collectors.toList());
        List<MessageUser> messageUserList = ids.size() == 0 ? null : messageUserService.getMessageUserByMessageIds(ids);
        if (ObjectUtils.isEmpty(messageUserList)) {
            throw new RuntimeException("得到 List<MessageUser> 失败");
        }

        // 将List<Message>转换为List<MessageVO>
        List<MessageVO> messageVOList = messageList
                .stream()
                .map(new Function<Message, MessageVO>() {
                    @Override
                    public MessageVO apply(Message message) {

                        // 给 messageVO 的 id、title、content、sendUserName、receiveUserCount、readCount 属性赋值
                        MessageVO messageVO = BeanCopyUtils.copyBean(message, MessageVO.class);

                        // 给 messageVO 的 receives 属性赋值
                        String receives = messageUserList
                                .stream()
                                .filter(new Predicate<MessageUser>() {
                                    @Override
                                    public boolean test(MessageUser messageUser) {
                                        return Objects.equals(messageUser.getMessageId(), message.getId());
                                    }
                                })
                                .map(new Function<MessageUser, String>() {
                                    @Override
                                    public String apply(MessageUser messageUser) {
                                        return messageUser.getReceiveUserName();
                                    }
                                })
                                .collect(Collectors.joining(","));
                        messageVO.setReceives(receives);

                        // 给 messageVO 的 createTime 属性赋值
                        messageVO.setCreateTime(DateTimeUtil.dateFormat(message.getCreateTime()));

                        return messageVO;
                    }
                })
                .collect(Collectors.toList());

        return PageInfoUtil.copyMap(oldPageInfo, messageVOList);
    }

    @Override
    @Transactional
    public void sendMessage(MessageSendDTO messageSendDTO) {

        // 给 message 的 title、content 属性赋值
        Message message = BeanCopyUtils.copyBean(messageSendDTO, Message.class);
        Date now = new Date();
        // 给 message 的 createTime 属性赋值
        message.setCreateTime(now);
        // 给 message 的 sendUserId 属性赋值
        message.setSendUserId(webContext.getCurrentUser().getId());
        // 给 message 的 sendUserName 属性赋值
        message.setSendUserName(webContext.getCurrentUser().getUserName());
        // 给 message 的 sendRealName 属性赋值
        message.setSendRealName(webContext.getCurrentUser().getRealName());

        List<User> receiveUsers = userService.selectByIds(messageSendDTO.getReceiveUserIds());
        // 给 message 的 receiveUserCount 属性赋值
        message.setReceiveUserCount(receiveUsers.size());

        // 给 message 的 readCount 属性赋值
        message.setReadCount(0);

        int i = messageMapper.insertSelective(message);
        if (i <=0 ) {
            throw new RuntimeException("插入消息失败");
        }

        List<MessageUser> messageUserList = receiveUsers
                .stream()
                .map(user -> {
                    MessageUser messageUser = new MessageUser();
                    messageUser.setCreateTime(now);
                    messageUser.setReaded(false);
                    messageUser.setReceiveRealName(user.getRealName());
                    messageUser.setReceiveUserId(user.getId());
                    messageUser.setReceiveUserName(user.getUserName());
                    messageUser.setMessageId(message.getId());
                    return messageUser;
                })
                .collect(Collectors.toList());

        int inserts = messageUserMapper.inserts(messageUserList);
        if (inserts <= 0) {
            throw new RuntimeException("插入 MessageUser 失败");
        }
    }

}
